jetcrab\bytecode\statements/
function.rs1use crate::ast::Node;
2use crate::vm::instructions::Instruction;
3
4pub trait FunctionGenerator {
5 fn generate_function_declaration(&mut self, node: &Node);
6 fn generate_function_expression(&mut self, node: &Node);
7}
8
9pub trait FunctionCore {
10 fn instructions(&mut self) -> &mut Vec<Instruction>;
11 fn visit_node(&mut self, node: &Node);
12}
13
14impl<T> FunctionGenerator for T
15where
16 T: FunctionCore + crate::bytecode::scope::constants::ConstantManager,
17{
18 fn generate_function_declaration(&mut self, node: &Node) {
19 if let Node::FunctionDeclaration(decl) = node {
20 if let Some(id) = &decl.id {
23 if let Node::Identifier(name) = &**id {
24 let function_id = self.add_constant(format!("__FUNCTION_{}", name));
26 self.instructions()
27 .push(Instruction::PushConst(function_id));
28
29 self.instructions().push(Instruction::PushUndefined);
32 }
33 }
34
35 self.visit_node(&decl.body);
37 }
38 }
39
40 fn generate_function_expression(&mut self, node: &Node) {
41 if let Node::FunctionExpression(expr) = node {
42 self.visit_node(&expr.body);
45
46 let function_id = format!(
49 "__FUNCTION_EXPR_{}",
50 expr.id.as_ref().map(|_id| "named").unwrap_or("anonymous")
51 );
52 let constant_index = self.add_constant(function_id);
53 self.instructions()
54 .push(Instruction::PushConst(constant_index));
55 }
56 }
57}